#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/procfs.h>
#include "thread_extensions.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

/*
 ================================================================
 Error Detection
 ================================================================

 For those functions which can return a "reasonable" runtime
 error, go ahead and detect them.  And then abort.
 */

int PTHREAD_CREATE(pthread_t *new_thread_ID, const pthread_attr_t *attr,
      void *(*start_func)(void *), void *arg)
{
   int err;
   //pthread_t tid;

   if (!new_thread_ID)
   {
      fprintf(stderr, "TID cannot be NULL.\n");
      abort();
   }
   if ((err = pthread_create(new_thread_ID, attr, start_func, arg)))
   {
      perror(NULL);
      abort();
   }

   return 0;
}

int PTHREAD_ATTR_INIT(pthread_attr_t *a)
{
   int err;
   if ((err = pthread_attr_init(a)))
   {
      perror(NULL);
      abort();
   }

   return 0;
}

int PTHREAD_CONDATTR_INIT(pthread_condattr_t *a)
{
   int err;
   if ((err = pthread_condattr_init(a)))
   {
      perror(NULL);
      abort();
   }

   return 0;
}

int PTHREAD_MUTEXATTR_INIT(pthread_mutexattr_t *a)
{
   int err;
   if ((err = pthread_mutexattr_init(a)))
   {
      perror(NULL);
      abort();
   }

   return 0;
}

int SEM_INIT(sem_t *sem, int pshared, unsigned int value)
{
   if (sem_init(sem, pshared, value))
   {
      perror(NULL);
      abort();
   }

   return 0;
}

int SEM_WAIT(sem_t *arg) /* Ignore signal interruptions */
{
   while (sem_wait(arg) != 0)
   {
   }

   return 0;
}

/* A barrier for one thread to wait for lots of others. */
void thread_single_barrier(sem_t *barrier, int count)
{
   while (count > 0)
   {
      SEM_WAIT(barrier);
      count--;
   }
}
